package com.lhkj.ct.meta.modules.scheduling.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhkj.ct.base.model.dto.PageQuery;
import com.lhkj.ct.base.mybatis.core.metadata.SqlOrder;
import com.lhkj.ct.base.mybatis.extension.service.impl.IServiceImpl;
import com.lhkj.ct.base.utils.ShiroUtil;
import com.lhkj.ct.base.utils.Validate;
import com.lhkj.ct.meta.modules.scheduling.common.enums.AppointStatus;
import com.lhkj.ct.meta.modules.scheduling.common.enums.ScheduleStatus;
import com.lhkj.ct.meta.modules.scheduling.mapper.ScheAppointMapper;
import com.lhkj.ct.meta.modules.scheduling.mapper.SchedulingMapper;
import com.lhkj.ct.meta.modules.scheduling.model.entity.TblScheAppoint;
import com.lhkj.ct.meta.modules.scheduling.model.entity.TblScheduling;
import com.lhkj.ct.meta.modules.scheduling.service.ScheAppointService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * <p>
 *      预约记录表 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2023-10-29
 */
@Service
public class ScheAppointServiceImpl extends IServiceImpl<ScheAppointMapper, TblScheAppoint> implements ScheAppointService {

    @Resource
    private SchedulingMapper schedulingMapper;

    @Override
    public int insert(TblScheAppoint entity) {
        TblScheduling scheduling = schedulingMapper.selectSchedulingById(entity.getScheId());
        Validate.notNull(scheduling, "排班不存在或已取消！");
        Validate.validState(scheduling.getStatus() == ScheduleStatus.NORMAL, "排班已停号或已取消！");
        Validate.isTrue(scheduling.getResidueNum() > 0, "排班已约满，请选择其他时间段进行预约！");
        return getBaseMapper().insert(entity);
    }

    @Override
    public IPage<TblScheAppoint> selectAppointPage(TblScheAppoint appoint, PageQuery pageQuery) {
        return getBaseMapper().selectAppointPage(
                generatePage(pageQuery, SqlOrder.desc(TblScheAppoint::getCreateTime, "t")),
                appoint,
                pageQuery
        );
    }

    @Override
    public IPage<TblScheAppoint> selectAppointPageByPatient(TblScheAppoint appoint, PageQuery pageQuery) {
        return getBaseMapper().selectAppointPageByPatient(
                generatePage(pageQuery, SqlOrder.desc(TblScheAppoint::getCreateTime, "t")),
                appoint,
                pageQuery
        );
    }

    @Override
    public int updateState(AppointStatus status, String... ids) {
        LambdaUpdateWrapper<TblScheAppoint> wrapper = new LambdaUpdateWrapper<>();
        // 修改状态
        wrapper.set(TblScheAppoint::getStatus, status)
                // 签到
                .eq(status == AppointStatus.SIGNED, TblScheAppoint::getStatus, AppointStatus.UNSIGNED)
                // 治疗完成，必须是已签到才能完成
                .eq(status == AppointStatus.DONE, TblScheAppoint::getStatus, AppointStatus.SIGNED)
                // 取消预约，已完成或者已取消的不能取消
                .ne(status == AppointStatus.CANCEL, TblScheAppoint::getStatus, AppointStatus.DONE)
                // 预约记录编号
                .in(TblScheAppoint::getId, (Object[]) ids);
        if (status == AppointStatus.DONE) {
            wrapper
                    // 治疗人
                    .set(TblScheAppoint::getTreatDoc, ShiroUtil.getAuthUserInfo().getUserId())
                    // 治疗时间
                    .set(TblScheAppoint::getTreatTime, LocalDateTime.now());
        }
        return getBaseMapper().update(null, wrapper);
    }

    @Override
    public int userSign(String id) {
        TblScheAppoint appoint = getBaseMapper().getWithScheduling(id);
        Validate.notNull(appoint, "预约记录不存在！");
        Validate.validState(appoint.getStatus() == AppointStatus.UNSIGNED, "预约%s，不可再次签到！", appoint.getStatus().getLabel());
        Validate.isTrue(LocalDate.now().equals(appoint.getScheDate()), "签到需在预约治疗时间当天！");
        LambdaUpdateWrapper<TblScheAppoint> wrapper = new LambdaUpdateWrapper<>();
        // 修改状态
        wrapper.set(TblScheAppoint::getStatus, AppointStatus.SIGNED)
                // 预约记录编号
                .eq(TblScheAppoint::getId, id);
        return getBaseMapper().update(null, wrapper);
    }

    @Override
    public int userCancel(String id) {
        TblScheAppoint appoint = getBaseMapper().getWithScheduling(id);
        Validate.notNull(appoint, "预约记录不存在！");
        Validate.validState(appoint.getStatus() != AppointStatus.SIGNED, "预约已签到，请联系医护人员取消！");
        Validate.validState(appoint.getStatus() != AppointStatus.DONE, "预约已完成，不可取消！");
        Validate.validState(appoint.getStatus() != AppointStatus.CANCEL, "预约已取消，不可再次取消！");
        Validate.isTrue(LocalDate.now().isBefore(appoint.getScheDate()), "取消预约需提前一天，如需取消请联系医护人员！");
        LambdaUpdateWrapper<TblScheAppoint> wrapper = new LambdaUpdateWrapper<>();
        // 修改状态
        wrapper.set(TblScheAppoint::getStatus, AppointStatus.CANCEL)
                // 预约记录编号
                .eq(TblScheAppoint::getId, id);
        return getBaseMapper().update(null, wrapper);
    }
}
